package com.zyx.site.listener;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.exception.NacosException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.zyx.site.config.NacosDynamicRouteConfig;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;
import reactor.core.publisher.Flux;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 监听 Nacos 配置变化，刷新网关路由
 */
@Component
@Slf4j
public class NacosRouteRefreshListener {
    @Autowired
    private NacosConfigManager nacosConfigManager;

    @Autowired
    private NacosDynamicRouteConfig dynamicRouteConfig;

    @Autowired
    private ObjectMapper objectMapper;

    private static final String DATA_ID = "gateway-routes.yaml"; // Nacos Data ID
    private static final String GROUP = "DEFAULT_GROUP";         // 组名

    @PostConstruct
    public void init() throws NacosException {
        log.info("初始化 Nacos 路由监听器");
        // 初始化时读取一次路由配置
        String config = nacosConfigManager.getConfigService().getConfig(DATA_ID, GROUP, 5000);
        parseAndRefreshWithYAML(config);

        // 添加监听器，实时监听配置变化
        nacosConfigManager.getConfigService().addListener(DATA_ID, GROUP, new AbstractListener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                log.info("Nacos 配置已更新：{}", configInfo);
                parseAndRefreshWithYAML(configInfo);
            }
        });

    }

    /**
     * 解析 JSON 并刷新路由
     */
    private void parseAndRefreshWithJSON(String configInfo) {
        List<RouteDefinition> routes = Collections.emptyList();

        if (configInfo != null && !configInfo.trim().isEmpty()) {
            try {
                routes = JSON.parseArray(configInfo, RouteDefinition.class);
            } catch (Exception e) {
                log.warn("解析 Nacos 配置失败，使用空路由列表替代", e);
            }
        }
        dynamicRouteConfig.refreshRoutes(Flux.fromIterable(routes));
    }

    /**
     * 解析 YAML 并刷新路由
     */
    private void parseAndRefreshWithYAML(String configInfo) {
        log.info("解析YAML格式【Nacos配置】已更新：{}", configInfo);
        try {
            if (configInfo == null || configInfo.trim().isEmpty()) {
                log.warn("Nacos 配置为空");
                dynamicRouteConfig.refreshRoutes(Flux.fromIterable(Collections.emptyList()));
                return;
            }

            // 使用 SnakeYAML 解析 YAML 字符串
            Yaml yaml = new Yaml();
            Object obj = yaml.load(configInfo);

            if (!(obj instanceof List)) {
                log.error("配置格式不正确，不是一个列表");
                dynamicRouteConfig.refreshRoutes(Flux.fromIterable(Collections.emptyList()));
                return;
            }

            @SuppressWarnings("unchecked")
            List<Map<String, Object>> rawRoutes = (List<Map<String, Object>>) obj;

            // 将 Map 转换为 RouteDefinition
            List<RouteDefinition> routeDefinitions = rawRoutes.stream()
                    .map(map -> objectMapper.convertValue(map, RouteDefinition.class))
                    .collect(Collectors.toList());

            dynamicRouteConfig.refreshRoutes(Flux.fromIterable(routeDefinitions));

        } catch (Exception e) {
            log.error("解析 Nacos 路由配置失败", e);
            dynamicRouteConfig.refreshRoutes(Flux.fromIterable(Collections.emptyList()));
        }
    }
}
